package com.chuzhong.framework.aspectj;

import com.chuzhong.common.core.domain.BaseEntity;
import com.chuzhong.common.core.domain.model.LoginUser;
import com.chuzhong.common.utils.SecurityUtils;
import com.chuzhong.common.utils.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author ChuZhong
 * @Description 保存时给实体添加创建时间与更新时间
 * @date 2021/3/13
 */
@Aspect
@Configuration
public class InsertAspect {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    //定义切点方法
    @Pointcut("@annotation(com.chuzhong.common.annotation.InsertHandle) || execution(public * com.chuzhong.*.mapper.*Mapper*.insert*(..))")
    public void pointCut() {
    }

    //环绕通知
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("进入新增切点。。。。。。。");
        Object[] args = joinPoint.getArgs();
        try {
            if (args != null && args.length == 1) {
                Object obj = args[0];
                LoginUser loginUser = null;
                try {
                    loginUser = SecurityUtils.getLoginUser();
                } catch (Exception e) {
                }
                if (obj instanceof BaseEntity) {
                    BaseEntity entity = (BaseEntity) obj;
                    if (loginUser != null && loginUser.getUser() != null) {
                        if (StringUtils.isEmpty(entity.getCreateBy())) {
                            entity.setCreateBy(loginUser.getUsername());
                        }
                        if (StringUtils.isEmpty(entity.getUpdateBy())) {
                            entity.setUpdateBy(loginUser.getUsername());
                        }

                    }
                    if (entity.getCreateTime() == null) {
                        entity.setCreateTime(new Date());
                    }
                    if (entity.getUpdateTime() == null) {
                        entity.setUpdateTime(new Date());
                    }
                }

                Class aClass = obj.getClass();
                //判断是否是实体包下的实体
                if ("com.ruoyi.hotel.domain".equals(aClass.getPackage().getName())) {
                    Field[] fields = aClass.getDeclaredFields();
                    for (Field field : fields) {
                        try {
                            field.setAccessible(true);
                            if ("createdBy".equals(field.getName()) || "updatedBy".equals(field.getName())) {
                                if (field.get(obj) == null || "".equals(field.get(obj))) {
                                    if (loginUser != null && loginUser.getUser() != null) {
                                        field.set(obj, loginUser.getUsername());
                                    }
                                }
                            }
                            if ("createdTime".equals(field.getName()) || "updatedTime".equals(field.getName())) {
                                if (field.getType() == Date.class) {
                                    if (field.get(obj) == null) {
                                        field.set(obj, new Date());
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Object result = joinPoint.proceed(args);
        return result;
    }

    @Pointcut("@annotation(com.chuzhong.common.annotation.UpdateHandle) || execution(* com.chuzhong.*.mapper.*Mapper*.update*(..))")
    public void updatePointCut() {
    }

    @Around("updatePointCut()")
    public Object updateAround(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("进入更新切点。。。。。。。");
        Object[] args = joinPoint.getArgs();
        try {
            if (args != null && args.length == 1) {
                Object obj = args[0];
                LoginUser loginUser = null;
                try {
                    loginUser = SecurityUtils.getLoginUser();
                } catch (Exception e) {
                }
                if (obj instanceof BaseEntity) {
                    BaseEntity entity = (BaseEntity) obj;
                    if (loginUser != null && loginUser.getUser() != null) {
                        if (StringUtils.isEmpty(entity.getUpdateBy())) {
                            entity.setUpdateBy(loginUser.getUsername());
                        }
                    }
                    if (entity.getUpdateTime() == null) {
                        entity.setUpdateTime(new Date());
                    }
                    entity.setCreateTime(null);
                }

                Class aClass = obj.getClass();
                //判断是否是实体包下的实体
                if ("com.chuzhong.vote.domain".equals(aClass.getPackage().getName())) {
                    Field[] fields = aClass.getDeclaredFields();
                    for (Field field : fields) {
                        try {
                            field.setAccessible(true);
                            if ("updatedBy".equals(field.getName())) {
                                if (field.get(obj) == null || "".equals(field.get(obj))) {
                                    if (loginUser != null && loginUser.getUser() != null) {
                                        field.set(obj, loginUser.getUsername());
                                    }
                                }
                            }
                            if ("updatedTime".equals(field.getName())) {
                                if (field.getType() == Date.class) {
                                    if (field.get(obj) == null) {
                                        field.set(obj, new Date());
                                    }
                                }
                            }
                            if ("createdTime".equals(field.getName())) {
                                if (field.getType() == Date.class) {
                                    field.set(obj, null);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Object result = joinPoint.proceed(args);
        return result;
    }
}
